﻿namespace LeRenard
{
    /// <summary>
    /// Abstract base implementation of <see cref="IRange"/> of <typeparam name="T"/>,
    /// specifies a range between a minimum and a maximum value of <typeparamref name="T"/>.
    /// </summary>
    public abstract class Range<T> : IRange<T>
    {
        /// <summary>
        /// The minimum value of the range.
        /// </summary>
        public T Minimum { get { return _minimum; } }
        private readonly T _minimum;

        /// <summary>
        /// The maximum value of the range.
        /// </summary>
        public T Maximum { get { return _maximum; } }
        private readonly T _maximum;

        /// <summary>
        /// Creates a new <see cref="Range"/> object.
        /// </summary>
        /// <param name="minimum">The minimum value of the range.</param>
        /// <param name="maximum">The maximum value of the range.</param>
        public Range(T minimum, T maximum)
        {
            ThrowIf.Null(() => minimum);
            ThrowIf.Null(() => maximum);

            _minimum = minimum;
            _maximum = maximum;
        }

        /// <summary>
        /// Determines whether the given value of <typeparamref name="T"/> is within range.
        /// </summary>
        /// <param name="value">The value to be checked.</param>
        /// <param name="isMinimumIncluded">Determines whether the <see cref="Minimum"/> range is included in the comparison.</param>
        /// <param name="isMaximumIncluded">Determines whether the <see cref="Maximum"/> range is included in the comparison. </param>
        /// <returns>True when in range, false when not in range.</returns>
        public abstract bool IsInRange(T value, bool isMinimumIncluded = true, bool isMaximumIncluded = true);

        /// <summary>
        /// Returns a <see cref="String"/> that represents the object.
        /// </summary>
        /// <returns>A <see cref="String"/> that represents the object.</returns>
        public override string ToString()
        {
            return this.ToDebugString();
        }
    }
}
